﻿using Constants;
using DotNetOpenAuth.OAuth2;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace TestOAuth.Controllers
{
    public class HomeController : Controller
    {
        private WebServerClient _webServerClient = null;
        private static string _accessToken;
        public ActionResult Index()
        {
             ViewBag.AccessToken = Request.Form["AccessToken"] ?? "";
            ViewBag.RefreshToken = Request.Form["RefreshToken"] ?? "";
            ViewBag.Action = "";
            ViewBag.ApiResponse = "";

            InitWebServerClient();
            var accessToken = Request.Form["AccessToken"];
            if (string.IsNullOrEmpty(accessToken))
            {
                var authorizationState = _webServerClient.ProcessUserAuthorization(Request);
                
                if (authorizationState != null)
                {
                    ViewBag.AccessToken = authorizationState.AccessToken;
                    ViewBag.RefreshToken = authorizationState.RefreshToken;
                    ViewBag.Action = Request.Path;
                }
            }

            if (!string.IsNullOrEmpty(Request.Form.Get("submit.Authorize")))
            {
                //var userAuthorization = _webServerClient.PrepareRequestUserAuthorization(new[] { "bio", "notes" });
                //userAuthorization.Send(HttpContext);
                Oauth();
                Response.End();
            }
            else if (!string.IsNullOrEmpty(Request.Form.Get("submit.Refresh")))
            {
                var state = new AuthorizationState
                {
                    AccessToken = Request.Form["AccessToken"],
                    RefreshToken = Request.Form["RefreshToken"]
                };
                if (_webServerClient.RefreshAuthorization(state))
                {
                    ViewBag.AccessToken = state.AccessToken;
                    ViewBag.RefreshToken = state.RefreshToken;
                }
            }
            else if (!string.IsNullOrEmpty(Request.Form.Get("submit.CallApi")))
            {
                var resourceServerUri = new Uri(Paths.ResourceServerBaseAddress);
                var client = new HttpClient(_webServerClient.CreateAuthorizingHandler(accessToken));
                var body = client.GetStringAsync(new Uri(resourceServerUri, Paths.MePath)).Result;
                ViewBag.ApiResponse = body;
            }

            return View();
            //InitWebServerClient();//初始化webclient
            //var accessToken = Request.Form["AccessToken"] ?? "";//获取accessToken

            //////第一步是进行认证
            ////var userAuth = webclient.PrepareRequestUserAuthorization(new[] { "bio", "notes" });
            ////userAuth.Send(HttpContext);
            ////Response.End();

            //if (string.IsNullOrWhiteSpace(accessToken))//没有获取到授权码，请求授权
            //{
            //    //RequestToken();
            //    var state = webclient.ProcessUserAuthorization(Request);
            //    if (state != null)
            //    {
            //        _accessToken = state.AccessToken;
            //    }
            //}
            //else
            //{
            //    _accessToken = accessToken;
            //}
            //return View(_accessToken);
        }

        public ActionResult Auth()
        {
            InitWebServerClient();
            var authorizationState = _webServerClient.ProcessUserAuthorization(Request);

            if (authorizationState != null)
            {
                ViewBag.AccessToken = authorizationState.AccessToken;
                ViewBag.RefreshToken = authorizationState.RefreshToken;
                ViewBag.Action = Request.Path;
            }
            var userAuthorization = _webServerClient.PrepareRequestUserAuthorization(new[] { "bio", "notes" });
            userAuthorization.Send(HttpContext);
            Response.End();
            return View();
        }


        private void Oauth()
        {
            //InitWebServerClient();
            var authorizationState = _webServerClient.ProcessUserAuthorization(Request);

            if (authorizationState != null)
            {
                ViewBag.AccessToken = authorizationState.AccessToken;
                ViewBag.RefreshToken = authorizationState.RefreshToken;
                ViewBag.Action = Request.Path;
            }
            var userAuthorization = _webServerClient.PrepareRequestUserAuthorization(new[] { "bio", "notes" },new Uri("http://localhost:38502/Home/GetCode"));
            
            userAuthorization.Send(HttpContext);
            Response.End();
        }
        public void InitWebServerClient()
        {
            var authorizationServerUri = new Uri(baseAddress);
            var authorizationServer = new AuthorizationServerDescription
            {
                AuthorizationEndpoint = new Uri(authorizationServerUri, Paths.AuthorizePath),
                TokenEndpoint = new Uri(authorizationServerUri, Paths.TokenPath),               
            };
            _webServerClient = new WebServerClient(authorizationServer, Clients.Client1.Id, Clients.Client1.Secret);
            
        }

        public void RequestToken()
        {
            var state = _webServerClient.GetClientAccessToken(new[] { "bio", "notes" });
            _webServerClient.RequestUserAuthorization(new[] { "bio", "notes" });
            _accessToken = state.AccessToken;

        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }

        private static readonly string CLIENT_ID = "webclientdemo";
        public string baseAddress = "http://localhost:7983";
        public async Task<ActionResult> Redirect1(string code)
        {
           if(Request.HttpMethod=="POST")
            {
                var httpClient = new HttpClient();
                var queryDict = new Dictionary<string, string>
            {
                {"response_type", "token"},            
                {"scope", "notes" },
                {"redirect_uri", Clients.Client1.RedirectUrl},
                {"client_id", Clients.Client1.Id},
                {"client_secret", Clients.Client1.Secret},
                {"state", "123456789"},

            };

                var httpContent = new FormUrlEncodedContent(queryDict);
                var response = await httpClient.PostAsync(baseAddress +
                Paths.AuthorizePath, httpContent);
                //HttpRequestMessage msg = new HttpRequestMessage();
                //msg.Content = httpContent;
               
                //msg.RequestUri =new Uri(Paths.AuthorizationServerBaseAddress + Paths.TokenPath);
                //msg.Method = HttpMethod.Post;
                //var response = await httpClient.SendAsync(msg);
                return Content(await response.Content.ReadAsStringAsync());
            }
            else
            {
                return View();
            }
        }

        private string GetNonCryptoRandomDataAsBase64(int binaryLength)
        {
            var _random = new Random();
            byte[] buffer = new byte[binaryLength];
            _random.NextBytes(buffer);
            string uniq = Convert.ToBase64String(buffer);
            return uniq;
        }

        public ActionResult DemoRequestCode()
        {
            string xsrfKey = this.GetNonCryptoRandomDataAsBase64(16);//生成随机数
            string url = baseAddress + Paths.AuthorizePath + "?" +
                string.Format("client_id={0}&redirect_uri={1}&response_type={2}&state={3}",
                Clients.Client1.Id, "http://localhost:38502/Home/GetCode", "code", xsrfKey);
            var XsrfCookieName = "StateCode";
            HttpCookie xsrfKeyCookie = new HttpCookie(XsrfCookieName, xsrfKey);
            xsrfKeyCookie.HttpOnly = true;
            xsrfKeyCookie.Secure = FormsAuthentication.RequireSSL;
            Response.Cookies.Add(xsrfKeyCookie);

            return Redirect(url);
        }

        public async Task<ActionResult> GetCode(string code=null)
        {

            var httpClient = new HttpClient();
            var queryDict = new Dictionary<string, string>
            {
                {"grant_type", "authorization_code"},
                {"code", code},
                {"redirect_uri", "http://localhost:38502/Home/GetCode"},
                {"client_id", Clients.Client1.Id},
                {"client_secret", Clients.Client1.Secret}
            };

            var httpContent = new FormUrlEncodedContent(queryDict);
            var response = await httpClient.PostAsync(baseAddress +
                Paths.TokenPath, httpContent);

            var accessToken = response.Content.ReadAsStringAsync().Result;
            System.Web.Script.Serialization.JavaScriptSerializer json = new System.Web.Script.Serialization.JavaScriptSerializer();
            //json.Serialize(accessToken);
           var tokenclass= json.Deserialize<TokenClass>(accessToken);

            return Content(await response.Content.ReadAsStringAsync());

        }
    }

    public class TokenClass
    {

        public string access_token { get; set; }

        public string token_type { get; set; }

        public int expires_in { get; set; }

        public string refresh_token { get; set; }
    }
}